package edu.hcmus.sow.web.document;

import java.util.List;

import javax.validation.Valid;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import edu.hcmus.sow.domain.FileRevision;
import edu.hcmus.sow.domain.Folder;
import edu.hcmus.sow.service.DocumentService;
import edu.hcmus.sow.utils.SecurityUtil;

@Controller
public class FolderController {

   // ~ Instance fields
   // ================================================================================================
   @Autowired
   private DocumentService documentService;

   // ~ Folder's methods
   // ================================================================================================
   @RequestMapping("/folder/{id}")
   public ModelAndView viewFolder(@PathVariable("id") Integer id) {
      // get folders & files
      ModelAndView mav = buildFolderModel(id);

      // set parent folder
      mav.addObject("currentFolderID", id);
      mav.addObject("folderForm", new FolderForm(id));

      // set view name
      mav.setViewName("repository");

      return mav;
   }

   @RequestMapping("/ajax/folder/{id}")
   public ModelAndView ajaxLoadDocuments(@PathVariable("id") Integer id) {
      // get folders & files
      ModelAndView mav = buildFolderModel(id);

      // set view name
      mav.setViewName("controls/c_folder");

      return mav;
   }

   @RequestMapping(value = "/ajax/folder/add", method = RequestMethod.POST)
   public ModelAndView addFolder(@Valid FolderForm folderForm, BindingResult result) {
      ModelAndView mav = new ModelAndView();

      // validate
      validate(folderForm.getParentID(), folderForm.getFolderName(), result);

      if (result.hasErrors()) {
         mav.setViewName("controls/c_folder_form");
         return mav;
      }

      documentService.createFolder(folderForm.getParentID(), folderForm.getFolderName());

      // set add_folder_success
      mav.addObject("add_folder_success", "add_folder_success");
      mav.setViewName("controls/c_folder_form");
      return mav;
   }

   @RequestMapping(value = "/ajax/folder/{id}/rename", method = RequestMethod.POST)
   @ResponseBody
   public String renameFolder(@PathVariable("id") Integer id, @RequestParam("folderName") String folderName) {
      // get folder
      Folder folder = documentService.getFolderByID(id);

      // validate
      String message = validate(folder.getParentID(), folderName);

      if (!folder.getName().equalsIgnoreCase(folderName.trim())) {
         if (!"".equals(message))
            return message;
      }

      // rename folder
      documentService.renameFolder(folder, folderName);

      return "";
   }

   @RequestMapping(value = "/ajax/folder/{id}/delete", method = RequestMethod.POST)
   public ModelAndView deleteFolder(@PathVariable("id") Integer id) {
      ModelAndView mav = new ModelAndView();
      // get folder
      Folder folder = documentService.getFolderByID(id);

      // get parent id
      Integer parentID = folder.getParentID();

      documentService.deleteFolder(id);

      mav = ajaxLoadDocuments(parentID);
      return mav;
   }

   private ModelAndView buildFolderModel(Integer currentFolderID) {
      ModelAndView mav = new ModelAndView();

      // get folders list which in parent folder
      List<Folder> folders = documentService.getFoldersByParentID(currentFolderID);
      mav.addObject("folders", folders);

      // get files list which in the folder
      List<FileRevision> files = documentService.getLatestFilesVersionByFolderID(currentFolderID);
      mav.addObject("files", files);

      return mav;
   }

   private String validate(Integer parentID, String name) {
      String folderName = StringUtils.trim(name);

      if (StringUtils.isEmpty(folderName)) {
         return "Folder name must not be blank.";
      }
      // get current client id
      int clientID = SecurityUtil.getCurrentClient();

      // check name exists
      if (documentService.folderExists(clientID, parentID, folderName)) {
         return "Folder's name is exists.";
      }
      return "";
   }

   private void validate(Integer parentID, String name, Errors errors) {
      if (!errors.hasFieldErrors("folderName")) {
         String folderName = StringUtils.trim(name);

         if (StringUtils.isEmpty(folderName)) {
            errors.rejectValue("folderName", "err.folderName", "Folder name must not be blank.");
         }
         // get current client id
         int clientID = SecurityUtil.getCurrentClient();

         // check name exists
         if (documentService.folderExists(clientID, parentID, folderName)) {
            errors.rejectValue("folderName", "err.folderName", "Folder's name is exists.");
         }
      }
   }
}
